using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.OleDb;
using GeneratorLibrary.Client.Base;

namespace GeneratorLibrary.Client.iSeries {
    public class iSeriesOLEClassColumn : ClassColumnBase {
        OleDbType sqlDataType;

        public iSeriesOLEClassColumn(DataRow dr) : base(dr) { }

        protected override string getDotNetDataType(ref string DbDataType) {
            switch (DbDataType.ToLower()) {
                case "bigint":
                    DbDataType = "BigInt";
                    if (isPrimaryKey || (isForeignKey && !isNullable))
                        nullValue = "0";
                    return "long" + (isNullable ? "?" : "");
                case "binary":
                case "varbin":
                case "blob":
                case "rowid":
                case "xml":
                    DbDataType = "Binary";
                    return "byte[]";

                case "char":
                case "datalink":
                    DbDataType = "Char";
                    return "string";
                case "varchar":
                case "clob":
                    DbDataType = "VarChar";
                    return "string";
                case "long varchar":
                    DbDataType = "LongVarChar";
                    return "string";

                case "dbclob":
                case "VARG":
                    DbDataType = "VarWChar";
                    return "string";

                case "graphic":
                    DbDataType = "WChar";
                    return "string";

                case "date":
                    DbDataType = "DBDate";
                    return "DateTime" + (isNullable ? "?" : "");
                case "time":
                    DbDataType = "DBTime";
                    return "TimeSpan" + (isNullable ? "?" : "");
                case "timestmp":
                    DbDataType = "DBTimeStamp";
                    return "DateTime" + (isNullable ? "?" : "");

                case "decimal":
                case "decfloat":
                case "numeric":
                    DbDataType = "Decimal";
                    return "decimal" + (isNullable ? "?" : "");

                case "float":
                case "double":
                    DbDataType = "Double";
                    return "double" + (isNullable ? "?" : "");
                case "int":
                case "integer":
                    DbDataType = "Integer";
                    if (isPrimaryKey || (isForeignKey && !isNullable))
                        nullValue = "0";
                    return "int" + (isNullable ? "?" : "");
                case "real":
                    DbDataType = "Single";
                    return "Single" + (isNullable ? "?" : "");
                case "smallint":
                    DbDataType = "SmallInt";
                    if (isPrimaryKey || (isForeignKey && !isNullable))
                        nullValue = "0";
                    return "short" + (isNullable ? "?" : "");
                default:
                    DbDataType = "Char";
                    return "string";
            }
        }
        public override string GetDotNetDefaultCoalesce() {
            switch (sqlDataType) {
                case OleDbType.BigInt:
                case OleDbType.Decimal:
                case OleDbType.Single:
                case OleDbType.Double:
                case OleDbType.Numeric:
                case OleDbType.Integer:
                case OleDbType.SmallInt:
                    return "0";
                case OleDbType.DBDate:
                    return "DateTime.Now.Date";
                case OleDbType.DBTime:
                    return "DateTime.Now.TimeOfDay";
                case OleDbType.DBTimeStamp:
                    return "DateTime.Now";
                default:
                    if (dataType.ToLower() == "string")
                        return "string.Empty";
                    else
                        return "";
            }
        }
        protected override void generate() {
            if (isPrimaryKey && isIdentity) {
                memberName = "id";
                propertyName = "Id";
                extraMethod = "public bool IsNew() {\nreturn id == 0; \n}\n";
                allowsIDataModel = true;
            } else {
                memberName = columnName.Substring(0, 1).ToLower() + columnName.Remove(0, 1);
                propertyName = columnName.Substring(0, 1).ToUpper() + columnName.Remove(0, 1);
            }

            if (isNullable && nullValue != "null") {
                member = dataType + " " + memberName + " = " + nullValue + ";\n";
            } else {
                member = dataType + " " + memberName + ";\n";
            }
            property = "public " + dataType + " " + propertyName + " {\n" + "get { return " + memberName + "; }\nset{ " +
                memberName + " = value; }\n}\n";

            if (isPrimaryKey) {
                if (sqlDataType == OleDbType.Integer) {
                    if ((isNullable || isIdentity) && nullValue != "null") {
                        dacAttribute = "[PKOleColumn(\"" + columnName + "\", " + nullValue + ", " + columnOrder + ")]";
                    } else if (!isIdentity) {
                        dacAttribute = "[PKOleColumn(\"" + columnName + "\", " + columnOrder + ", " + isIdentity.ToString() + ")]";
                    } else {
                        dacAttribute = "[PKOleColumn(\"" + columnName + "\", " + columnOrder + ")]";
                    }
                } else {
                    dacAttribute = "[PKOleColumn(\"" + columnName + "\", OleDbType." + Enum.GetName(typeof(OleDbType), sqlDataType)
                        + ", " + nullValue + ", " + columnOrder + ", " + isIdentity.ToString() + ")]";
                }
            } else if (isIdentity) {
                if (sqlDataType == OleDbType.Integer) {
                    if (nullValue != "null")
                        dacAttribute = "[IdentityNotPKOleColumn(\"" + columnName + "\", " + nullValue + ", " + columnOrder + ")]";
                    else
                        dacAttribute = "[IdentityNotPKOleColumn(\"" + columnName + "\", " + columnOrder + ")]";
                } else {
                    dacAttribute = "[IdentityNotPKOleColumn(\"" + columnName + "\", OleDbType." + Enum.GetName(typeof(OleDbType), sqlDataType)
                        + ", " + nullValue + ", " + columnOrder + ")]";
                }
            } else if (sqlDataType == OleDbType.VarChar) {
                if (isNullable && nullValue != "null") {
                    dacAttribute = "[StringOleColumn(\"" + columnName + "\", " + nullValue + ", " + columnOrder + ")]";
                } else {
                    dacAttribute = "[StringOleColumn(\"" + columnName + "\", " + columnOrder + ")]";
                }
            } else {
                if (isNullable && nullValue != "null") {
                    dacAttribute = "[OleColumn(\"" + columnName + "\", OleDbType." + Enum.GetName(typeof(OleDbType), sqlDataType)
                        + ", " + nullValue + ", " + columnOrder + ")]";
                } else {
                    dacAttribute = "[OleColumn(\"" + columnName + "\", OleDbType." + Enum.GetName(typeof(OleDbType), sqlDataType)
                        + ", " + columnOrder + ")]";
                }
            }
        }

        protected override void setDbDataType(string DbDataType) {
            try {
                sqlDataType = (OleDbType)Enum.Parse(typeof(OleDbType), DbDataType, true);
            } catch {
                throw new Exception("Currently, this program is not set up to deal with columns of type '" + DbDataType + "'. Column = " + columnName);
            }
        }
    }
}
